<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        button {
            margin: 5px;
        }

        .box {
            float: left;
            position: relative;
            width: 200px;
            height: 200px;
            background-color: var(--bg);
            line-height: 200px;
            font-size: 60px;
        }
    </style>
</head>

<body>
    <div class="showbox">
        <button @click="box1">点击1</button>
        <button @click="box2">点击2</button>
        <button @click="box3">点击3</button>
        <button @click="box4">点击4</button>
        <br>
        <div class="box" v-show='showbox1' style="--bg:red">1</div>
        <div class="box" v-if='ifbox2' style="--bg:purple">2</div>
        <div class="box" v-if='ifbox3' style="--bg:yellow">3</div>
        <div class="box" v-show='showbox4' style="--bg:brown">4</div>
    </div>
    <script>

        ; ((w, doc) => {
            class Vue {
                constructor(options) {
                    const { el, data, methods } = options
                    this.ele = doc.querySelector(el);
                    this.data = data;
                    this.methods = methods;
                    this.eventPool = new Map();
                    this.showPool = new Map();
                    this.init()
                }
                init() {
                    Object.keys(this.data).forEach(k => {
                        this.initProxy(this, k);
                    })

                    this.initView(this.ele);

                    this.initEvent(this.eventPool);

                }
                initEvent(eventPool) {
                    for (let [k, v] of eventPool) {
                        k.addEventListener('click', v.fn.bind(this), false)
                    }
                    this.changeEvent(null, this.showPool)
                }
                initProxy(vm, k) {
                    Object.defineProperty(vm, k, {
                        enumerable: true,
                        configurable: true,
                        get() {
                            return this.data[k]
                        },
                        set(val) {
                            this.data[k] = val;
                            this.changeEvent(k, this.showPool)
                        }
                    })
                }
                initView(node) {
                    const childNodes = node.childNodes;
                    if (!childNodes.length) {
                        console.log(childNodes);
                        return;
                    }
                    childNodes.forEach(dom => {
                        if (dom.nodeType === 1) {
                            const vshow = dom.getAttribute('v-show');
                            const vif = dom.getAttribute('v-if');
                            const evet = dom.getAttribute('@click');
                            if (vif) {
                                this.showPool.set(dom, {
                                    type: 'vif',
                                    show: this.data[vif],
                                    key: vif
                                })
                            } else if (vshow) {
                                this.showPool.set(dom, {
                                    type: 'vshow',
                                    show: this.data[vshow],
                                    key: vshow
                                })
                            }
                            if (evet) {
                                this.eventPool.set(dom, {
                                    type: 'click',
                                    fn: this.methods[evet],
                                    event: evet
                                })
                            }
                            this.initView(dom)
                        }
                    })
                }
                changeEvent(data, showPool) {
                    if (!data) {
                        console.log(6);
                        for (let [k, v] of showPool) {
                            console.log(v);
                            switch (v.type) {
                                case 'vshow':
                                    !v.show && (k.style.display = 'none');
                                    break;
                                case 'vif':
                                    v.comment = doc.createComment('v-if')
                                    !v.show && k.parentNode.replaceChild(v.comment, k);
                                    break;

                            }
                        }
                        return
                    }
                    for (let [k, v] of showPool) {
                        console.log(666666);
                        if (data === v.key) {
                            switch (v.type) {
                                case 'vshow':
                                    v.show ? (k.style.display = 'none') : (k.style.display = 'block')
                                    v.show = !v.show;
                                    break;
                                case 'vif':
                                    v.show ? k.parentNode.replaceChild(v.comment, k) : v.comment.parentNode.replaceChild(k, v.comment)
                                    v.show = !v.show;
                                    break;

                            }
                        }

                    }

                }
            }
            w.Vue = Vue;
        })(window, document)
    </script>
    <script>

        const app = new Vue({
            el: '.showbox',
            data: {
                showbox1: false,
                ifbox2: false,
                ifbox3: false,
                showbox4: false
            },
            methods: {
                box1() {
                    console.log(66);
                    this.showbox1 = !this.showbox1;
                },
                box2() {
                    this.ifbox2 = !this.ifbox2;
                },
                box3() {
                    this.ifbox3 = !this.ifbox3;
                },
                box4() {
                    this.showbox4 = !this.showbox4;
                },
            }
        })

        console.log(app);
    </script>
</body>

</html>